package edu.rit.varapp.utilities;

import edu.rit.varapp.datalayer.Customer;
import edu.rit.varapp.datalayer.CustomerOps;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 * CSVParser allows an administrator to parse a CSV file with customer information directly into the database.
 * @author Eric Kisner
 */
public class CSVParser {

    private File csv = null;
    private CustomerOps cOps;

    public CSVParser( CustomerOps cOps ) {
        this.cOps = cOps;
        initCSV();
    }

    /**
     * This method will parse the csv file that the user has previously chosen, and return a list of customers.
     *
     * @throws ArrayIndexOutOfBoundsException We actually want this to be a checked exception, because
     *                                        the user may format the csv file incorrectly, so we want to
     *                                         notify them of that.
     */
    //TODO: put some fancy "Processing line x" splash screen in here = AWESOMESAUCE
    public ArrayList<Customer> parseData() throws IOException, SQLException, ArrayIndexOutOfBoundsException {
        ArrayList<Customer> ret = new ArrayList<Customer>();
        BufferedReader in = new BufferedReader( new FileReader( csv ) );
        String line = null;
        while( (line = in.readLine()) != null ) {
            //Regex found on stackoverflow.com
            String otherThanQuote = " [^\"] ";
            String quotedString = String.format( " \" %s* \" ", otherThanQuote );
            String regex = String.format( "(?x) " + // enable comments, ignore white spaces
                    ",                         " + // match a comma
                    "(?=                       " + // start positive look ahead
                    "  (                       " + //   start group 1
                    "    %s*                   " + //     match 'otherThanQuote' zero or more times
                    "    %s                    " + //     match 'quotedString'
                    "  )*                      " + //   end group 1 and repeat it zero or more times
                    "  %s*                     " + //   match 'otherThanQuote'
                    "  $                       " + // match the end of the string
                    ")                         ", // stop positive look ahead
                                          otherThanQuote, quotedString, otherThanQuote );

            String[] tokens = line.split( regex );
            Customer customer = new Customer( cOps.newEntityId(),
                                              tokens[0],
                                              tokens[1],
                                              tokens[2],
                                              tokens[3],
                                              tokens[4],
                                              tokens[5],
                                              tokens[6],
                                              tokens[7],
                                              tokens[8] );
            ret.add( customer );
        }
        return ret;
    }

    private void initCSV() {
        JFileChooser chooser = getFileChooser();
        JOptionPane.showMessageDialog( chooser, "Please choose the CSV file you wish to be imported." );
        int r = chooser.showOpenDialog( chooser );
        if( r == JFileChooser.APPROVE_OPTION ) {
            csv = chooser.getSelectedFile();
        } else {
            return;
        }
    }

    private JFileChooser getFileChooser() {
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory( new File( "." ) );
        chooser.setFileFilter( new javax.swing.filechooser.FileFilter() {

            @Override
            public boolean accept( File f ) {
                return f.getName().toLowerCase().endsWith( ".txt" )
                       || f.getName().toLowerCase().endsWith( ".doc" )
                       || f.getName().toLowerCase().endsWith( ".csv" )
                       || f.isDirectory();
            }

            @Override
            public String getDescription() {
                return "CSV File";
            }
        } );
        return chooser;
    }
}
